﻿using CloudFranceTriple.Models;
using CloudFranceTriple.WebRole.Models;
using System;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using WebMatrix.WebData;

namespace CloudFranceTriple.WebRole.Areas.Forum.Controllers
{
    [HandleError]
    public class PostController : BaseController
    {
        private cloudfrAboq2RsDMEntities db = new cloudfrAboq2RsDMEntities();

        private readonly IWebSecurityWrapper _webSecurity;
        public PostController()
        {
            this._webSecurity = new WebSecurityWrapper();
        }

        public PostController(IWebSecurityWrapper webSecurity)
            : base(webSecurity)
        {
            this._webSecurity = webSecurity;
        }
        // TopicId=4
        // GET: /Forum/Post/Index/4 

        [AllowAnonymous()]
        [Authorize(Roles = "RoleMember,RoleFans,RoleBaffMember,RoleAdminForum")]
        [ChildActionOnly]
        public ActionResult PollItem(int? TopicId)
        {
            ViewBag.Topic_Id = TopicId;
            ViewBag.IsAuthor = db.ForumTopicSet.Find(TopicId).IsUnlocked && CheckAutorRights(db.ForumTopicSet.Find(TopicId));

            if (TopicId != null)
                ViewBag.IsTopicAuthor = (_webSecurity.CurrentUserName == db.ForumTopicSet.Find(TopicId).AuthorForumTopic);
            else
                ViewBag.IsTopicAuthor = User.IsInRole("RoleAuthorPollOnPortail");


            var query = db.PollSet.Where(poll => poll.ForumTopic_Id == (TopicId ?? 0)).Include("PollAnswerSet").Include("PollAnswerSet.PollUserSet");
            return PartialView("_PollItem", query);
        }

        private void MarkPostAsRead(int topicId, int userId)
        {
            ForumPostReadSet forumpostread;

            var postIdAlreadyReadInThisTopic = db.ForumPostSet.Where(p1 => p1.ForumTopic_Id == topicId).Join(db.ForumPostReadSet, post => post.Id, read => read.ForumPost_Id, (post, read) => read).Where(read2 => read2.UserId == userId).Select(read3 => read3.ForumPost_Id);
            var postAlreadyReadInThisTopic = db.ForumPostSet.Where(post => postIdAlreadyReadInThisTopic.Contains(post.Id));

            //Si l'utilisateur vient dans le sujet pour la première fois, il faut incrémenter le compteur du sujet :
            if (postIdAlreadyReadInThisTopic.Count() == 0)
            {
                db.ForumTopicSet.Find(topicId).NumberHasBeenSeenForumTopic++;
                db.SaveChanges();
            }

            var forumpostset = db.ForumPostSet.Where(p1 => p1.ForumTopic_Id == topicId).Except(postAlreadyReadInThisTopic);
            foreach (ForumPostSet post in forumpostset)
            {
                forumpostread = new ForumPostReadSet() { ForumPost_Id = post.Id, UserId = userId };
                db.ForumPostReadSet.Add(forumpostread);
            }
            db.SaveChanges();
        }

        // TopicId
        // GET: /Forum/Post/Index/14 
        [AllowAnonymous()]
        [Authorize(Roles = "RoleMember,RoleFans,RoleBaffMember,RoleAdminForum")]
        public ActionResult Index(int id)
        {
            if (id == 0) RedirectToAction("Index", "Home", routeValues: new { area = "" });

            //Vérifier les droits d'accès par rapport à ForumSecurity
            if (!base.ForumIdAllowed.Contains(db.ForumCategorySet.Find(db.ForumTopicSet.Where(t1 => t1.Id == id).First().ForumCategory_Id).Forum_Id))
                ThrowSecurityException();

            if (User.Identity.IsAuthenticated)
                MarkPostAsRead(id, new UsersContext().UserProfiles.SingleOrDefault(u => u.UserName == User.Identity.Name).UserId);
            // Compter les visiteurs anonymes comme des lecteurs
            // Todo : exclure les moteurs de recherche
            else
            {
                db.ForumTopicSet.Find(id).NumberHasBeenSeenForumTopic++;
                db.SaveChanges();
            }

            var topic = db.ForumTopicSet.Find(id);
            ViewBag.SiteMapPath1 = HttpUtility.HtmlDecode(topic.ForumCategorySet.ForumSet.LabelForum);
            ViewBag.SiteMapPath2 = HttpUtility.HtmlDecode(topic.ForumCategorySet.LabelForumCategory);
            ViewBag.SiteMapPath3 = HttpUtility.HtmlDecode(topic.LabelForumTopic);

            ViewBag.Topic_Id = topic.Id;
            ViewBag.Category_Id = topic.ForumCategory_Id;
            ViewBag.IsUnLocked = topic.IsUnlocked;
            var forumpostset = db.ForumPostSet.Where(p1 => p1.ForumTopic_Id == id).Include(f => f.ForumTopicSet).OrderBy(p2 => p2.Id);

            ViewBag.ShowCreate = (topic.IsUnlocked && (UserRightLevelByCategoryId(topic.ForumCategory_Id, User.Identity.IsAuthenticated) >= RightLevel.Author));

            ViewBag.LocalizedUserRights = String.Format("({0})", CloudFranceTriple.WebRole.Models.RightLevel.GetRightLevelSelectListItems()[UserRightLevelByCategoryId(topic.ForumCategory_Id, User.Identity.IsAuthenticated)].Text);

            return View(forumpostset.ToList());
        }

        //
        // GET: /Forum/Post/Create/TopicId/PostIdtoQuote

        [Authorize(Roles = "RoleMember,RoleFans,RoleBaffMember,RoleAdminForum")]
        public ActionResult Create(int id = 0, int id2 = 0)
        {
            var topic = db.ForumTopicSet.Find(id);
            if (!topic.IsUnlocked) ThrowSecurityException(topic);

            ViewBag.Topic_Id = topic.Id;
            ViewBag.ForumTopic_Id = new SelectList(db.ForumTopicSet, "Id", "LabelForumTopic", id);

            if (id2 > 0)
            {
                var post2 = db.ForumPostSet.Find(id2);
                var quotedPost = String.Format("<p>\r\n<fieldset style=\"display: block;text-align: left;border: 1px solid #fffffe; border-radius: 8px;\">\r\n<legend style=\"display: block; color: #fffffe;\">{0} {1} : </legend>\r\n{2}</fieldset>\r\n</p>\r\n",
                    post2.PostMessage_Author,
                    CloudFranceTriple.WebRole.Properties.Resources.PostQuotedSaid,
                    post2.PostMessage_Message);
                ViewBag.QuotedPost = quotedPost;
                ViewBag.QuotedPostId = id2;
                //return View(new ForumPostSet { PostMessage_Message = quotedPost });
            }
            return View();
        }

        //
        // POST: /Forum/Post/Create

        [HttpPost]
        [ValidateAntiForgeryToken]
        [ValidateInput(false)]
        [Authorize(Roles = "RoleMember,RoleFans,RoleBaffMember,RoleAdminForum")]
        public ActionResult Create(ForumPostSet forumpostset)
        {
            if (!db.ForumTopicSet.Find(forumpostset.ForumTopic_Id).IsUnlocked) ThrowSecurityException(forumpostset);

            if (ModelState.IsValid)
            {
                var _quotedPost = Request.Form["QuotedPostId"];
                Int32 _quotedPostId = Int32.Parse(_quotedPost);

                if (_quotedPostId > 0)
                {
                    var post2 = db.ForumPostSet.Find(_quotedPostId);
                    var quotedPost = String.Format("<fieldset style=\"display: block; margin-top: 4px; margin-bottom: 4px; padding: 4px; text-align: left;border: 1px solid #fffffe; border-radius: 8px;\"><legend style=\"display: block; color: #fffffe;\">{0} {1} : </legend>{2}</fieldset>",
                        post2.PostMessage_Author,
                        CloudFranceTriple.WebRole.Properties.Resources.PostQuotedSaid,
                        post2.PostMessage_Message);
                    forumpostset.PostMessage_Message = String.Format("{0}<br /><br />{1}", quotedPost, forumpostset.PostMessage_Message);
                }

                forumpostset.PostMessage_Author = User.Identity.Name;
                forumpostset.PostMessage_CreationDate = System.DateTime.UtcNow;
                forumpostset.PostMessage_AuthorAdressIp = Request.UserHostAddress.Substring(0, Request.UserHostAddress.Length > 15 ? 15 : Request.UserHostAddress.Length);

                db.ForumPostSet.Add(forumpostset);
                db.SaveChanges();

                // Mettre à jour le compteur de post de l'utilisateur.
                var uc = new CloudFranceTriple.WebRole.Models.UsersContext();
                var userProfile = uc.UserProfiles.Find(_webSecurity.CurrentUserId);
                userProfile.ForumMessagePostedCounter++;
                uc.Entry(userProfile).State = System.Data.EntityState.Modified;
                uc.SaveChanges();

                // Mettre à jour les compteurs de la catégorie:
                var cat = db.ForumCategorySet.Find(db.ForumTopicSet.Find(forumpostset.ForumTopic_Id).ForumCategory_Id);
                cat.LastPostAuthor = forumpostset.PostMessage_Author;
                cat.LastPostCreationDate = forumpostset.PostMessage_CreationDate;
                cat.LastPostId = forumpostset.Id;
                cat.LastPostTopicId = forumpostset.ForumTopic_Id;
                cat.NumberOfMessage++;
                db.Entry(cat).State = System.Data.EntityState.Modified;
                db.SaveChanges();

                return RedirectToAction("Index", "Post", new { id = forumpostset.ForumTopic_Id, area = "Forum" });
            }

            ViewBag.Topic_Id = forumpostset.ForumTopic_Id;
            ViewBag.ForumTopic_Id = new SelectList(db.ForumTopicSet, "Id", "LabelForumTopic", forumpostset.ForumTopic_Id);
            return View(forumpostset);
        }

        //
        // GET: /Forum/Post/Edit/5

        [Authorize(Roles = "RoleMember,RoleFans,RoleBaffMember,RoleAdminForum")]
        public ActionResult Edit(int id = 0)
        {
            ForumPostSet forumpostset = db.ForumPostSet.Find(id);

            if (forumpostset == null)
            {
                return HttpNotFound();
            }
            if (!forumpostset.ForumTopicSet.IsUnlocked) ThrowSecurityException(forumpostset);
            if (!CheckAutorRights(forumpostset))
                ThrowSecurityException(forumpostset);

            ViewBag.Topic_Id = forumpostset.ForumTopic_Id;
            ViewBag.ForumTopic_Id = new SelectList(db.ForumTopicSet, "Id", "LabelForumTopic", forumpostset.ForumTopic_Id);
            return View(forumpostset);
        }

        //
        // POST: /Forum/Post/Edit/5

        [HttpPost]
        [ValidateAntiForgeryToken]
        [ValidateInput(false)]
        [Authorize(Roles = "RoleMember,RoleFans,RoleBaffMember,RoleAdminForum")]
        public ActionResult Edit(ForumPostSet forumpostset)
        {
            if (!db.ForumTopicSet.Find(forumpostset.ForumTopic_Id).IsUnlocked) ThrowSecurityException(forumpostset);
            if (!CheckAutorRights(forumpostset))
                ThrowSecurityException(forumpostset);
            if (ModelState.IsValid)
            {
                forumpostset.PostMessage_CreationDate = DateTime.UtcNow;

                // Mettre à jour les compteurs de la catégorie:
                var cat = db.ForumCategorySet.Find(db.ForumTopicSet.Find(forumpostset.ForumTopic_Id).ForumCategory_Id);
                if (cat.LastPostId == forumpostset.Id)
                    cat.LastPostCreationDate = forumpostset.PostMessage_CreationDate;

                db.Entry(forumpostset).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index", new { id = forumpostset.ForumTopic_Id });
            }
            ViewBag.Topic_Id = forumpostset.ForumTopic_Id;
            ViewBag.ForumTopic_Id = new SelectList(db.ForumTopicSet, "Id", "LabelForumTopic", forumpostset.ForumTopic_Id);
            return View(forumpostset);
        }

        //
        // GET: /Forum/Post/Delete/5

        [Authorize(Roles = "RoleMember,RoleFans,RoleBaffMember,RoleAdminForum")]
        public ActionResult Delete(int id = 0)
        {
            ForumPostSet forumpostset = db.ForumPostSet.Find(id);
            ViewBag.Topic_Id = forumpostset.ForumTopic_Id;
            if (forumpostset == null)
            {
                return HttpNotFound();
            }
            if (!forumpostset.ForumTopicSet.IsUnlocked) ThrowSecurityException(forumpostset);
            if (!CheckAutorRights(forumpostset))
                ThrowSecurityException(forumpostset);

            return View(forumpostset);
        }

        //
        // POST: /Forum/Post/Delete/5

        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        [Authorize(Roles = "RoleMember,RoleFans,RoleBaffMember,RoleAdminForum")]
        public ActionResult DeleteConfirmed(int id)
        {
            ForumPostSet forumpostset = db.ForumPostSet.Find(id);
            if (!forumpostset.ForumTopicSet.IsUnlocked) ThrowSecurityException(forumpostset);
            if (!CheckAutorRights(forumpostset))
                ThrowSecurityException(forumpostset);

            ViewBag.Topic_Id = forumpostset.ForumTopic_Id;
            db.ForumPostSet.Remove(forumpostset);
            db.SaveChanges();

            // Mettre à jour le compteur de post de l'utilisateur.
            var uc = new CloudFranceTriple.WebRole.Models.UsersContext();
            var userProfile = uc.UserProfiles.SingleOrDefault(u => u.UserName.ToLower() == forumpostset.PostMessage_Author.ToLower());
            if (userProfile != null)
            {
                userProfile.ForumMessagePostedCounter--;
                uc.Entry(userProfile).State = System.Data.EntityState.Modified;
                uc.SaveChanges();
            }

            // Mettre à jour les compteurs de la catégorie:
            var cat = db.ForumCategorySet.Find(db.ForumTopicSet.Find(forumpostset.ForumTopic_Id).ForumCategory_Id);

            var _postInCat = db.ForumPostSet.Where(post => post.ForumTopicSet.ForumCategory_Id == cat.Id).ToList();
            if (_postInCat.Count > 0)
            {
                var newLastPost = db.ForumPostSet.Find(_postInCat.Max(post2 => post2.Id));
                if (newLastPost != null)
                {
                    cat.LastPostAuthor = newLastPost.PostMessage_Author;
                    cat.LastPostCreationDate = newLastPost.PostMessage_CreationDate;
                    cat.LastPostId = newLastPost.Id;
                    cat.LastPostTopicId = newLastPost.ForumTopic_Id;
                    cat.NumberOfMessage--;
                }
                else
                {
                    cat.LastPostAuthor = null;
                    cat.LastPostCreationDate = null;
                    cat.LastPostId = null;
                    cat.LastPostTopicId = null;
                    cat.NumberOfMessage = 0;
                }
            }
            else
            {
                cat.LastPostAuthor = null;
                cat.LastPostCreationDate = null;
                cat.LastPostId = null;
                cat.LastPostTopicId = null;
                cat.NumberOfMessage = 0;
            }

            db.Entry(cat).State = System.Data.EntityState.Modified;
            db.SaveChanges();

            return RedirectToAction("Index", "Post", new { id = forumpostset.ForumTopic_Id, area = "forum" });
        }

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
    }
}